package com.huidu.bitrade.controller;

import static com.huidu.bitrade.util.MessageResult.error;
import static com.huidu.bitrade.util.MessageResult.success;
import static org.springframework.util.Assert.hasText;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.huidu.bitrade.constant.ActivityType;
import com.huidu.bitrade.entity.*;
import com.huidu.bitrade.service.*;
import com.huidu.bitrade.service.ActivityOrderService;
import com.huidu.bitrade.util.GeneratorUtil;
import com.huidu.bitrade.vendor.provider.SMSProvider;
import com.huidu.bitrade.constant.BooleanEnum;
import com.huidu.bitrade.constant.MemberLevelEnum;
import com.huidu.bitrade.constant.SysConstant;
import com.huidu.bitrade.entity.*;
import com.huidu.bitrade.entity.transform.AuthMember;
import com.huidu.bitrade.service.*;
import com.huidu.bitrade.util.DateUtil;
import com.huidu.bitrade.util.MessageResult;
import com.huidu.bitrade.vendor.provider.result.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("activity")
public class ActivityController  extends BaseController {
	@Autowired
    private ActivityService activityService;

	@Autowired
    private ActivityOrderService activityOrderService;

	@Autowired
    private LocaleMessageSourceService sourceService;

	@Autowired
    private RedisTemplate redisTemplate;

	@Autowired
    private MemberService memberService;

	@Autowired
    private CoinService coinService;

//    @Autowired
//    private CountryService countryService;

    @Autowired
    private SMSProvider smsProvider;

    @Resource
    private LocaleMessageSourceService localeMessageSourceService;

	@Autowired
    private MemberWalletService walletService;
    @Autowired
    private RestTemplate restTemplate;

	private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @RequestMapping(value = "/code", method = RequestMethod.POST)
    public MessageResult attendActivityCode(@SessionAttribute(SysConstant.SESSION_MEMBER) AuthMember user) throws Exception {
        Member member = memberService.findOne(user.getId());
        Assert.hasText(member.getMobilePhone(), localeMessageSourceService.getMessage("NOT_BIND_PHONE"));
        RestResult result;
        String randomCode = String.valueOf(GeneratorUtil.getRandomNumber(100000, 999999));
        if ("86".equals(member.getCountry().getAreaCode())) {
            result = smsProvider.sendVerifyMessage(member.getMobilePhone(), randomCode);
        } else {
            result = smsProvider.sendInternationalMessage(randomCode, member.getCountry().getAreaCode(), member.getMobilePhone());
        }
        if (result.getCode() == 0) {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            String key = SysConstant.PHONE_ATTEND_ACTIVITY_PREFIX + member.getMobilePhone();
            valueOperations.getOperations().delete(key);
            // 缓存验证码
            valueOperations.set(key, randomCode, 10, TimeUnit.MINUTES);
            return success(localeMessageSourceService.getMessage("SEND_SMS_SUCCESS"));
        } else {
            return error(localeMessageSourceService.getMessage("SEND_SMS_FAILED"));
        }
    }
    @RequestMapping("page-query")
    public MessageResult page(int pageNo, int pageSize, int step) {
    	MessageResult mr = new MessageResult();
        Page<Activity> all = activityService.queryByStep(pageNo, pageSize, step);
        mr.setCode(0);
        mr.setData(all);
        return mr;
    }

    @RequestMapping("detail")
    public MessageResult detail(Long id) {
        Activity detail = activityService.findOne(id);
        Assert.notNull(detail, "validate id!");
        return success(detail);
    }

    @RequestMapping("attend")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult attendActivity(@SessionAttribute(SysConstant.SESSION_MEMBER) AuthMember user,
                                        BigDecimal amount,
                                        Long activityId,
                                        String code,
                                        String aims) {
        Member member = memberService.findOne(user.getId());
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            return MessageResult.error(500, sourceService.getMessage("NUMBER_OF_ILLEGAL"));
        }
    	Assert.notNull(activityId, "valid activity id");
    	// 检查验证码是否正确
    	hasText(code, sourceService.getMessage("MISSING_VERIFICATION_CODE"));
        hasText(aims, sourceService.getMessage("MISSING_PHONE_OR_EMAIL"));
        ValueOperations valueOperations = redisTemplate.opsForValue();

        if (member.getMobilePhone() != null && aims.equals(member.getMobilePhone())) {
            Object info = valueOperations.get(SysConstant.PHONE_ATTEND_ACTIVITY_PREFIX + member.getMobilePhone());
            if ( info==null ||!info.toString().equals(code)) {
                return MessageResult.error(sourceService.getMessage("VERIFICATION_CODE_INCORRECT"));
            } else {
                valueOperations.getOperations().delete(SysConstant.PHONE_ATTEND_ACTIVITY_PREFIX + member.getMobilePhone());
            }
        } else if (member.getEmail() != null && aims.equals(member.getEmail())) {
            Object info = valueOperations.get(SysConstant.PHONE_ATTEND_ACTIVITY_PREFIX + member.getEmail());
            if (!info.toString().equals(code)) {
                return MessageResult.error(sourceService.getMessage("VERIFICATION_CODE_INCORRECT"));
            } else {
                valueOperations.getOperations().delete(SysConstant.PHONE_ATTEND_ACTIVITY_PREFIX + member.getEmail());
            }
        } else {
            return MessageResult.error("参与活动失败！");
        }

        // 是否经过实名认证
        if(member.getMemberLevel()== MemberLevelEnum.GENERAL){
            return MessageResult.error(500,"请先进行实名认证");
        }

        //是否被禁止交易
        if(member.getTransactionStatus().equals(BooleanEnum.IS_FALSE)){
            return MessageResult.error(sourceService.getMessage("CANNOT_TRADE"));
        }

        // 检查活动是否存在
        Activity activity = activityService.findOne(activityId);
        Assert.notNull(activity, "此活动不存在!");

//        if(activity.getType().equals(ActivityType.HDZ_PLEDGE)){
//            return MessageResult.error("活动暂未开放！");
//        }

        // 一级邀请人数是否满足
        if(activity.getLeveloneCount() > 0) {
        	if(member.getFirstLevel() < activity.getLeveloneCount()) {
        		return MessageResult.error(500, "您的一级好友数量低于"+activity.getLeveloneCount());
        	}
        }
        // 云矿机检查
        if(activity.getType().equals(ActivityType.MINE)) {
            if(amount.intValue() < 1) {
                return MessageResult.error("请输入正确的购买数量！");
            }
        }
        //检查活动是否是正确的类型
        if(activity.getType().equals(ActivityType.IPO_RUSH) || activity.getType().equals(ActivityType.IPO_SHARE)|| activity.getType().equals(ActivityType.UNKNOWN)) {
            return MessageResult.error("该活动类型需前往币币交易对参与！");
        }
        // 检查活动是否在进行中
        if(activity.getStep() != 1) {
        	return MessageResult.error("活动不在进行中状态！");
        }
        // 检查当前时间是否处在活动期间内
        long currentTime = Calendar.getInstance().getTimeInMillis(); // 当前时间戳
        try {
            if(!activity.getStartTime().equals(activity.getEndTime())){
                if(dateTimeFormat.parse(activity.getEndTime()).getTime() < currentTime) {
                    return MessageResult.error("活动已结束！");
                }
                if(dateTimeFormat.parse(activity.getStartTime()).getTime() > currentTime) {
                    return MessageResult.error("活动尚未开始！");
                }
            }
		} catch (ParseException e) {
			e.printStackTrace();
			return MessageResult.error("发生未知错误！Code：9901");
		}

        // 自由认购类型，检查是否超过最大发售量
        if(activity.getType().equals(ActivityType.FREE_SUBSCRIBE)|| activity.getType().equals(ActivityType.MINE)) {
            if(activity.getTradedAmount().compareTo(activity.getTotalSupply()) >= 0) {
                return MessageResult.error("已超出认购总数！");
            }
        }
        // 最低起兑量/最低锁仓量
        if(activity.getMinLimitAmout().compareTo(BigDecimal.ZERO) > 0) {
            if(activity.getMinLimitAmout().compareTo(amount) > 0) {
                return MessageResult.error("不能低于最低起兑量！");
            }
        }
        if(activity.getMaxLimitAmout().compareTo(BigDecimal.ZERO) > 0 || activity.getLimitTimes() > 0) {
            // 最高兑换量/最高锁仓量(先获取已下单的量)
            List<ActivityOrder> orderDetailList = activityOrderService.findAllByActivityIdAndMemberId(member.getId(), activityId);
            BigDecimal alreadyAttendAmount = BigDecimal.ZERO;
            int alreadyAttendTimes = 0;
            if(orderDetailList != null) {
                alreadyAttendTimes = orderDetailList.size();
                for(int i = 0; i < orderDetailList.size(); i++) {
                    if(activity.getType().equals(ActivityType.PARTITION)) {
                        alreadyAttendAmount = alreadyAttendAmount.add(orderDetailList.get(i).getFreezeAmount());
                    }else {
                        alreadyAttendAmount = alreadyAttendAmount.add(orderDetailList.get(i).getAmount());
                    }
                }
            }
            // 最高限购量
            log.error("最大限购："+activity.getMaxLimitAmout()+"----购买数量---："+amount+"--活动类型---"+activity.getType().getTypeName()+"---CoinType--"+activity.getAcceptUnit());
            if(activity.getMaxLimitAmout().compareTo(BigDecimal.ZERO) > 0) {
                if(alreadyAttendAmount.add(amount).compareTo(activity.getMaxLimitAmout()) > 0) {
                    return MessageResult.error("不能超过最高兑换量！");
                }
            }
            // 个人限购次数
            if(activity.getLimitTimes() > 0) {
                if(activity.getLimitTimes() < alreadyAttendTimes + 1) {
                    return MessageResult.error("超过限购次数！");
                }
            }
        }

    	// 检查持仓要求
    	if(activity.getHoldLimit().compareTo(BigDecimal.ZERO) > 0 && activity.getHoldUnit() != null && activity.getHoldUnit() != "") {
    		MemberWallet holdCoinWallet = walletService.findByCoinUnitAndMemberId(activity.getHoldUnit(), member.getId());
    		if (holdCoinWallet == null) {
                return MessageResult.error("持仓要求钱包不存在！");
            }
    		if(holdCoinWallet.getIsLock().equals(BooleanEnum.IS_TRUE)){
                return MessageResult.error("持仓要求钱包已锁定！");
            }
    		if(holdCoinWallet.getBalance().compareTo(activity.getHoldLimit()) < 0) {
    			return MessageResult.error("您的" + activity.getHoldUnit() +"持仓数量不满足条件！");
    		}
    	}

        // 查询币种是否存在
        Coin coin;
        coin = coinService.findByUnit(activity.getAcceptUnit());
        if (coin == null) {
            return MessageResult.error(sourceService.getMessage("NONSUPPORT_COIN"));
        }

        // 检查钱包是否可用
        MemberWallet acceptCoinWallet = walletService.findByCoinUnitAndMemberId(activity.getAcceptUnit(), member.getId());
        if (acceptCoinWallet == null || acceptCoinWallet == null) {
            return MessageResult.error(sourceService.getMessage("NONSUPPORT_COIN"));
        }
        if(acceptCoinWallet.getIsLock().equals(BooleanEnum.IS_TRUE)){
            return MessageResult.error("钱包已锁定");
        }

        // 检查余额是否充足
        BigDecimal totalAcceptCoinAmount = BigDecimal.ZERO;
        if(activity.getType().equals(ActivityType.PARTITION)) { // 持仓瓜分
            totalAcceptCoinAmount = amount.setScale(activity.getAmountScale(), BigDecimal.ROUND_HALF_DOWN);
        }else if(activity.getType().equals(ActivityType.FREE_SUBSCRIBE)) {  // 自由认购
            totalAcceptCoinAmount = activity.getPrice().multiply(amount).setScale(activity.getAmountScale(), BigDecimal.ROUND_HALF_DOWN);
        }else if(activity.getType().equals(ActivityType.MINE)) {  // 矿机认购
            totalAcceptCoinAmount = activity.getPrice().multiply(amount).setScale(activity.getAmountScale(), BigDecimal.ROUND_HALF_DOWN);
        }else if(activity.getType().equals(ActivityType.LOCK)) { // 锁仓认购
            // 保存了锁仓数量和门槛费
            totalAcceptCoinAmount = amount.add(activity.getLockedFee()).setScale(activity.getAmountScale(), BigDecimal.ROUND_HALF_DOWN);
        }else if(activity.getType().equals(ActivityType.HDZ_PLEDGE)){//hdz质押
            totalAcceptCoinAmount = amount.setScale(activity.getAmountScale(), RoundingMode.HALF_DOWN);
        }

        if(acceptCoinWallet.getBalance().compareTo(totalAcceptCoinAmount) < 0){
        	return MessageResult.error("余额不足,币种:" + activity.getAcceptUnit());
        }

        //如果是质押，调用质押接口，直接返回
        if(activity.getType().equals(ActivityType.HDZ_PLEDGE)){
            String serviceName = "member";
            String url = "http://" + serviceName + "/member/activityHdz/pledge?memberId="+ user.getId()+"&amount="+amount+"&activityId="+activity.getId();
            log.info("========调用member服务质押接口=======url:{}",url);
            ResponseEntity<MessageResult> result = restTemplate.getForEntity(url, MessageResult.class);
            log.info("========返回=======result:{}",result);
            if (result.getStatusCode().value() == 200) {
                return result.getBody();
            }else{
                log.info("=========调用member服务质押接口=======");
                return MessageResult.error("参与质押失败");
            }

        }

        ActivityOrder activityOrder = new ActivityOrder();
        activityOrder.setActivityId(activityId);
        if(activity.getType().equals(ActivityType.PARTITION)) {
            activityOrder.setAmount(BigDecimal.ZERO);
            activityOrder.setFreezeAmount(totalAcceptCoinAmount); // 冻结资产数量（仅持仓瓜分需要设置此值）
        }else if(activity.getType().equals(ActivityType.FREE_SUBSCRIBE)||activity.getType().equals(ActivityType.MINE)||activity.getType().equals(ActivityType.HDZ_PLEDGE)) {
            activityOrder.setAmount(amount); // 实际下单数量
            activityOrder.setFreezeAmount(BigDecimal.ZERO);
        }else if(activity.getType().equals(ActivityType.LOCK)){
            activityOrder.setAmount(amount); // 实际锁仓数量
            activityOrder.setFreezeAmount(totalAcceptCoinAmount); // 这里冻结的资产包含了用户实际锁仓数量和门槛费
        }else{
        	activityOrder.setAmount(BigDecimal.ZERO);
        	activityOrder.setFreezeAmount(BigDecimal.ZERO);
        }
        activityOrder.setBaseSymbol(activity.getAcceptUnit());
        activityOrder.setCoinSymbol(activity.getUnit());
        activityOrder.setCreateTime(DateUtil.getCurrentDate());
        activityOrder.setMemberId(member.getId());
        activityOrder.setPrice(activity.getPrice());
        activityOrder.setState(1); //未成交
        activityOrder.setTurnover(totalAcceptCoinAmount);//作为资产冻结或扣除资产的标准，锁仓活动中，此项目作为参与数量
        activityOrder.setType(activity.getType());
//        if(activity.getType().equals(ActivityType.FREE_SUBSCRIBE)&&activity.getIsCsproject()==8){
//            //认购创世股东项目
//            //下单数量取整
//            int cSamount=amount.intValue();
//            //更新累积购买数量和创世股东等级
//           memberService.updateBuyCsNumCsLevel(member,cSamount);
//        }
            MessageResult mr = activityOrderService.saveActivityOrder(member.getId(), activityOrder);

        if (mr.getCode() != 0) {
            return MessageResult.error(500, "活动参与失败:" + mr.getMessage());
        }else {
        	return MessageResult.success("恭喜！认购成功！");
        }
    }

    @RequestMapping("getmemberrecords")
    public MessageResult getMemberRecordsByActivityId(@SessionAttribute(SysConstant.SESSION_MEMBER) AuthMember user, Long activityId) {

    	Assert.notNull(activityId, "valid activity id");
    	List<ActivityOrder> orderList = activityOrderService.findAllByActivityIdAndMemberId(user.getId(), activityId);

    	return success(orderList);
    }

    /**
     * 获取用户参与的所有订单
     * @param user
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping("getmyorders")
    public MessageResult getMemberOrders(@SessionAttribute(SysConstant.SESSION_MEMBER) AuthMember user, @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {

    	Assert.notNull(user, "valid user");
    	Page<ActivityOrder> orderList = activityOrderService.finaAllByMemberId(user.getId(), pageNo, pageSize);
    	for(int i = 0; i < orderList.getContent().size(); i++) {
    		Activity item = activityService.findOne(orderList.getContent().get(i).getActivityId());
    		if(item != null) {
    			orderList.getContent().get(i).setActivityName(item.getTitle());
    		}
    	}
    	return success(orderList);
    }
}
